<?php

namespace app\admin\controller;

use app\admin\service\ConsultantService;
use app\admin\service\ExportBlackService;
use app\admin\service\OfflineExportService;
use app\admin\service\OnlineExportService;
use app\admin\service\ReportService;
use app\admin\service\UserService;
use app\BaseController;
use app\model\ConsultArticleModel;
use app\model\ConsultArticleTestModel;
use app\model\ConsultBlacklistModel;
use app\model\ConsultEvaluateModel;
use app\model\ConsultOfflineModel;
use app\model\ConsultOfflineResultModel;
use app\model\ConsultOfflineTaskModel;
use app\model\ConsultOnlineMessageModel;
use app\model\ConsultOnlineModel;
use app\model\ConsultOnlineResultModel;
use app\model\ConsultQuestionModel;
use app\model\ConsultTimeModel;
use app\model\FollowUserModel;
use app\model\MessageModel;
use app\model\not_del\ConsultDelLogModel;
use app\model\UserModel;
use app\socket\Server;
use think\App;
use think\swoole\Websocket;

class Consult extends BaseController
{
    public function __construct(App $app)
    {
        parent::__construct($app);
    }

    /**
     * 咨询师选择器
     * @return bool|string
     */
    public function consultSelector(): bool|string
    {
        try {
            $UserModel = new UserModel();
            $data = $UserModel->where([
                ['unit_id','=',$this->userData['unit_id']],
                ['role_mode','=',2]
            ])->field('id,name')->select()->toArray();
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 是否有红点
     * @return bool|string
     */
    public function isDot(): bool|string
    {
        try {
            $ConsultOnlineModel = new ConsultOnlineModel();
            $ConsultOfflineModel = new ConsultOfflineModel();
            $ConsultDelLogModel = new ConsultDelLogModel();
            $del = $ConsultDelLogModel->where([
                ['uid', '=', $this->userData['id']],
                ['type', '=', 1]
            ])->column('type_id');
            $del2 = $ConsultDelLogModel->where([
                ['uid', '=', $this->userData['id']],
                ['type', '=', 2]
            ])->column('type_id');
            switch ($this->userData['role_mode']) {
                case 2:
                    //咨询师
                    $is_dot = $ConsultOnlineModel->where([
                        ['consult_id', '=', $this->userData['id']],
                        ['admin_dot', '=', 1],
                        ['id', 'not in', $del]
                    ])->value('id');
                    if (!$is_dot) {
                        $is_dot = $ConsultOfflineModel->where([
                            ['consult_id', '=', $this->userData['id']],
                            ['admin_dot', '=', 1],
                            ['id', 'not in', $del2]
                        ])->value('id');
                    }
                    break;
                case 3:
                    //用户
                    $is_dot = $ConsultOnlineModel->where([
                        ['uid', '=', $this->userData['id']],
                        ['user_dot', '=', 1],
                        ['id', 'not in', $del]
                    ])->value('id');
                    if (!$is_dot) {
                        $is_dot = $ConsultOfflineModel->where([
                            ['uid', '=', $this->userData['id']],
                            ['user_dot', '=', 1],
                            ['id', 'not in', $del2]
                        ])->value('id');
                    }
                    break;
                default:
                    $is_dot = 0;
            }
            return success([
                'is_dot' => $is_dot ? 1 : 0
            ]);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 排班间隔时段选择器
     * @return bool|string
     */
    public static function SchedulingDuration(): bool|string
    {
        $data = [
            ['value' => 5, 'name' => '5分钟'],
            ['value' => 10, 'name' => '10分钟'],
            ['value' => 15, 'name' => '15分钟'],
            ['value' => 20, 'name' => '20分钟'],
            ['value' => 30, 'name' => '30分钟'],
            ['value' => 60, 'name' => '60分钟'],
        ];
        return success($data);
    }

    /**
     * 拉黑时长选择器
     * @return bool|string
     */
    public function blackoutDuration(): bool|string
    {
        $data = [
            ['time' => 3 * 24 * 60 * 60, 'day' => 3, 'name' => '三天'],
            ['time' => 7 * 24 * 60 * 60, 'day' => 7, 'name' => '七天'],
            ['time' => 30 * 24 * 60 * 60, 'day' => 30, 'name' => '三十天'],
            ['time' => 0, 'day' => 0, 'name' => '永久'],
        ];
        return success($data);
    }

    /**
     * 拉黑原因选择器
     * @return bool|string
     */
    public function blackReason(): bool|string
    {
        $data = [
            ['key' => 1, 'value' => '恶意发起咨询'],
            ['key' => 2, 'value' => '骂人'],
            ['key' => 3, 'value' => '评估未赴约'],
            ['key' => 4, 'value' => '线下预约失信'],
        ];
        return success($data);
    }

    /**
     * 问题类型选择器
     * @return bool|string
     */
    public function questionSelector(): bool|string
    {
        try {
            $where = [];
            $where[] = ['status', '=', 1];
            $where[] = ['unit_id', '=', $this->userData['unit_id']];
            $ConsultQuestionModel = new ConsultQuestionModel();
            $data = $ConsultQuestionModel->field('id,name')->where($where)->order('id desc')->select()->toArray();
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 问题类型列表
     * @return bool|string
     */
    public function questionList(): bool|string
    {
        try {
            $param = $this->request->param();
            $where = [];
            $where[] = ['unit_id', '=', $this->userData['unit_id']];
            $ConsultQuestionModel = new ConsultQuestionModel();
            $query = $ConsultQuestionModel->where($where);
            $data = $query->paginate($param['pageSize'])->toArray();
            $data['ids'] = $query->column('id');
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 问题类型添加
     * @return bool|string
     */
    public function questionAdd(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'name|类型名称' => 'require',
            ]);
            $param['unit_id'] = $this->userData['unit_id'];
            $param['time'] = time();
            $ConsultQuestionModel = new ConsultQuestionModel();
            $ConsultQuestionModel->insert($param);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 问题类型编辑
     * @return bool|string
     */
    public function questionUpdate(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require',
            ]);
            $ConsultQuestionModel = new ConsultQuestionModel();
            $info = $ConsultQuestionModel->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            $info->save($param);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 问题类型删除
     * @return bool|string
     */
    public function questionDel(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultQuestionModel = new ConsultQuestionModel();
            if (is_array($id)) {
                $ConsultQuestionModel->where('id', 'in', $id)->update([
                    'is_del' => 1,
                    'del_time' => time()
                ]);
            } else {
                $ConsultQuestionModel->where('id', '=', $id)->update([
                    'is_del' => 1,
                    'del_time' => time()
                ]);
            }
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 问题类型状态修改
     * @return bool|string
     */
    public function questionStatus(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $status = $this->request->param('status');
            $ConsultQuestionModel = new ConsultQuestionModel();
            if (is_array($id)) {
                $ConsultQuestionModel->where('id', 'in', $id)->update([
                    'status' => $status
                ]);
            } else {
                $ConsultQuestionModel->where('id', '=', $id)->update([
                    'status' => $status
                ]);
            }
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询记录-咨询师选择器
     * @return bool|string
     */
    public function ConsultOnlineSelector(): bool|string
    {
        try {
            $ConsultOnlineModel = new ConsultOnlineModel();
            $ConsultIds = $ConsultOnlineModel->where('unit_id', '=', $this->userData['unit_id'])->distinct(true)->column('consult_id');
            if (!$ConsultIds) return success();
            $UserModel = new UserModel();
            $data = $UserModel->where('id', 'in', $ConsultIds)->field('id,name')->select()->toArray();
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询记录
     * @return bool|string
     */
    public function onlineList(): bool|string
    {
        try {
            $param = $this->request->param();
            $UserModel = new UserModel();
            $where = [];
            if (!empty($param['start_time']) && !empty($param['end_time'])) {
                $where[] = ['time', 'between', [$param['start_time'], $param['end_time']]];
            } else {
                if (!empty($param['start_time'])) {
                    $where[] = ['time', '>=', $param['start_time']];
                }
                if (!empty($param['end_time'])) {
                    $where[] = ['time', '<=', $param['end_time']];
                }
            }
            if (!empty($param['question_id'])) {
                $where[] = ['question_id', 'in', $param['question_id']];
            }
            if (!empty($param['consult_id'])) {
                $where[] = ['consult_id', 'in', $param['consult_id']];
            }
            if (isset($param['is_follow']) && strlen($param['is_follow']) > 0) {
                $where[] = ['is_follow', '=', $param['is_follow']];
            }
            if (isset($param['is_blacklist']) && strlen($param['is_blacklist']) > 0) {
                $where[] = ['is_blacklist', '=', $param['is_blacklist']];
            }
            if (isset($param['is_end']) && strlen($param['is_end']) > 0) {
                $where[] = ['is_end', '=', $param['is_end']];
            }
            if (!empty($param['uid'])) {
                $where[] = ['uid', '=', $param['uid']];
            }
            if (!empty($param['name'])) {
                $uids = $UserModel->where([
                    ['unit_id', '=', $this->userData['unit_id']],
                    ['name|username', 'like', '%' . $param['name'] . '%']
                ])->column('id');
                if (!empty($uids)) {
                    $where[] = ['uid', 'in', $uids];
                } else {
                    $where[] = ['id', '=', -1];
                }
            }
            if (!empty($param['sex'])) {
                //普通用户的性别筛选
                $ids = $UserModel->where([
                    ['unit_id', '=', $this->userData['unit_id']],
                    ['sex', '=', $param['sex']]
                ])->column('id');
                if (!empty($ids)) {
                    $where[] = ['uid', 'in', $ids];
                } else {
                    $where[] = ['id', '=', -1];
                }
            }
            if (!empty($param['class_id'])) {
                $ids = $UserModel->where('department_id', 'in', $param['class_id'])->column('id');
                if (!empty($ids)) {
                    $where[] = ['uid', 'in', $ids];
                } else {
                    $where[] = ['id', '=', -1];
                }
            }
            if ($this->userData['role_mode'] == 2) {
                $where[] = ['consult_id', '=', $this->userData['id']];
            }
            if (!empty($param['id'])) {
                $where[] = ['id', 'in', $param['id']];
            }
            $where[] = ['unit_id', '=', $this->userData['unit_id']];
            $ConsultDelLogModel = new ConsultDelLogModel();
            $delId = $ConsultDelLogModel->where([
                ['uid', '=', $this->userData['id']],
                ['type', '=', 1]
            ])->column('type_id');
            if (!empty($delId)) {
                $where[] = ['id', 'not in', $delId];
            }
            $ConsultOnlineModel = new ConsultOnlineModel();
            $query = $ConsultOnlineModel->where($where);
            $data = $query->with([
                'user', 'consult', 'questionName'
            ])->order('id desc')->paginate($param['pageSize'])->toArray();
            $data['ids'] = $query->column('id');
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     *  线上高级筛选导出
     * @return bool|string
     */
    public function onlineAdvancedFilteringExport(): bool|string
    {
        try {
            $param = $this->request->param();
            $param['role_mode'] = $this->userData['role_mode'];
            $param['unit_id'] = $this->userData['unit_id'];
            $param['user_id'] = $this->userData['id'];
            $OnlineExportService = new OnlineExportService($this->app);
            $ret = $OnlineExportService->OnlineExport($param);
            if (!$ret) throw new \Exception($OnlineExportService->getMessage());
            return success($OnlineExportService->getResult());
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询记录-详情
     * @return bool|string
     */
    public function onlineInfo(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOnlineModel = new ConsultOnlineModel();
            $data = $ConsultOnlineModel->with([
                'questionName',
                'consult',
                'user'
            ])->find($id);
            if (!$data) throw new \Exception('参数错误！');
            $data->save([
                'admin_dot' => 0
            ]);
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询记录删除
     * @return bool|string
     */
    public function onlineDel(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require'
            ]);
            $ConsultantService = new ConsultantService($this->app);
            $ConsultantService->del($param['id'], 1, $this->userData);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询内容
     * @return bool|string
     */
    public function onlineMessageList(): bool|string
    {
        $ConsultOnlineModel = new ConsultOnlineModel();
        $ConsultOnlineModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require'
            ]);
            $info = $ConsultOnlineModel->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            $ConsultOnlineMessageModel = new ConsultOnlineMessageModel();
            $data = $ConsultOnlineMessageModel->where('online_id', '=', $param['id'])
                ->with([
                    'user',
                    'RatingScale',
                    'ConsultOnlineResult'
                ])->select()->toArray();
            $dot = 0;
            foreach ($data as &$item) {
                if ($item['type'] == 1 && $item['admin_dot'] == 1) {
                    $item['admin_dot'] = 0;
                } else {
                    $dot = 1;
                }
            }
            $ConsultOnlineMessageModel->where([
                ['online_id', '=', $param['id']],
                ['type', '=', 1]
            ])->update([
                'admin_dot' => 0
            ]);
            if ($dot) {
                $info->save([
                    'admin_dot' => 0
                ]);
            }
            $ConsultOnlineModel->commit();
            return success($data);
        } catch (\Exception $e) {
            $ConsultOnlineModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询-发送消息
     * @param Websocket $websocket
     * @return bool|string
     */
    public function onlineSendMessage(Websocket $websocket): bool|string
    {
        $ConsultOnlineModel = new ConsultOnlineModel();
        $ConsultOnlineModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'online_id|咨询记录' => 'require|integer|max:11',
                'type|类型' => 'require',
            ]);
            $info = $ConsultOnlineModel->find($param['online_id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->is_end == 1) throw new \Exception('会话已结束！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('当前咨询师才能回复！');
            $info->user_dot = 1;
            $info->save();
            $ConsultOnlineMessageModel = new ConsultOnlineMessageModel();
            $num = $ConsultOnlineMessageModel->where([
                ['uid', '=', $this->userData['id']],
                ['online_id', '=', $param['online_id']]
            ])->count();
            if (!empty($param['rating_scale_id'])) {
                if (!is_array($param['rating_scale_id'])) throw new \Exception('参数错误！');
                $MessageData = [];
                foreach ($param['rating_scale_id'] as $v) {
                    $MessageData[] = [
                        'online_id' => $param['online_id'],
                        'rating_scale_id' => $v,
                        'type' => $param['type'],
                        'uid' => $this->userData['id'],
                        'who' => 2,
                        'time' => time(),
                        'user_dot' => 1
                    ];
                }
                if (!empty($MessageData) > 0) {
                    $ConsultOnlineMessageModel->insertAll($MessageData);
                }
            } else {
                $param['uid'] = $this->userData['id'];
                $param['who'] = 2;
                $param['time'] = time();
                $param['user_dot'] = 1;
                $ConsultOnlineMessageModel->insert($param);
            }
            if ($num) {
                //系统消息
                $MessageModel = new MessageModel();
                $MessageModel->insert([
                    'uid' => $info['uid'],
                    'type' => 17,
                    'title' => '发起咨询',
                    'content' => '咨询师' . $this->userData['name'] . '回复了您发起的线上咨询，请及时查看吧！',
                    'time' => time()
                ]);
            }
            $ConsultOnlineModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['uid']]);
            if ($num) {
                $socketServer->push($fd, json_encode([
                    'type' => 'message',
                    'content' => [
                        'type' => 17,
                        'title' => '发起咨询',
                        'content' => '咨询师' . $this->userData['name'] . '回复了您发起的线上咨询，请及时查看吧！',
                        'img' => match (17) {
                            3, 4, 5, 7, 8, 9, 10 => '/icon_task/202411/07_1730960087672c5ad715646.png',//测评任务消息
                            6, 11, 1, 2, 14, 15, 16, 23 => '/icon_task/202411/07_1730960430672c5c2ee2c98.png',//预警报告消息-系统通知-公告-危机干预
                            17 => '/icon_task/202411/07_1730944047672c1c2fd624c.png',//预约咨询消息
                            22 => '/icon_task/202411/07_1730941588672c1294c2e1e.png',//物联网消息
                        },
                        'time' => time()
                    ]
                ]), $websocket);
            }
            $socketServer->push($fd, json_encode([
                'type' => 'consultOnline',
                'content' => [
                    'id' => $param['online_id'],
                    'type' => 1
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultOnlineModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询-结束会话
     * @param Websocket $websocket
     * @return bool|string
     */
    public function onlineEnd(Websocket $websocket): bool|string
    {
        $UserModel = new UserModel();
        $UserModel->startTrans();
        try {
            $id = $this->request->param('id');
            $ConsultOnlineModel = new ConsultOnlineModel();
            $info = $ConsultOnlineModel->find($id);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('只能咨询师结束会话！');
            if ($info->is_end == 1) throw new \Exception('已结束会话！');
            $info->admin_dot = 0;
            $info->user_dot = 0;
            $info->is_end = 1;
            $info->end_time = time();
            $info->save();
            $ConsultOnlineMessageModel = new ConsultOnlineMessageModel();
            $ConsultOnlineMessageModel->where('online_id', '=', $info->id)->update([
                'admin_dot' => 0,
                'user_dot' => 0
            ]);
            $UserModel->where('id', '=', $this->userData['id'])->inc('consult_online_num')->save();
            //更新用户表，档案更新时间
            $UserModel->where('id', '=', $info->uid)->update(['archive_update_time' => time(), 'is_normal' => 1]);
            $UserModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['uid']]);
            $socketServer->push($fd, json_encode([
                'type' => 'consultOnline',
                'content' => [
                    'id' => $id,
                    'type' => 2
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            $UserModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询-加入黑名单
     * @param Websocket $websocket
     * @return bool|string
     */
    public function onlineAddBlacklist(Websocket $websocket): bool|string
    {
        $ConsultOnlineModel = new ConsultOnlineModel();
        $ConsultOnlineModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'source_id|来源ID' => 'require|integer|max:11',
                'duration|时长' => 'require',
                'reason|原因' => 'require',
            ]);
            $info = $ConsultOnlineModel->find($param['source_id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('咨询师不匹配！');
            if ($info->is_blacklist == 1) throw new \Exception('不可重复拉黑！');
            $param['unit_id'] = $this->userData['unit_id'];
            $param['uid'] = $info->uid;
            $param['consult_id'] = $info->consult_id;
            $param['source'] = 1;
            $param['time'] = time();
            $ConsultBlacklistModel = new ConsultBlacklistModel();
            $info->blacklist_id = $ConsultBlacklistModel->insertGetId($param);
            $info->is_blacklist = 1;
            $UserModel = new UserModel();
            if ($info->is_end == 0) {
                $info->is_end = 1;
                $info->end_time = time();
                $UserModel->where('id', '=', $info->consult_id)->inc('consult_online_num')->save();
            }
            //取消红点
            $info->admin_dot = 0;
            $info->user_dot = 0;
            $info->save();
            $ConsultOnlineMessageModel = new ConsultOnlineMessageModel();
            $ConsultOnlineMessageModel->where('online_id', '=', $info->id)->update([
                'admin_dot' => 0,
                'user_dot' => 0
            ]);
            //更新用户表，档案更新时间
            $UserModel->where('id', '=', $info->uid)->update(['archive_update_time' => time(), 'is_normal' => 1]);
            $ConsultOnlineModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['uid']]);
            $socketServer->push($fd, json_encode([
                'type' => 'consultOnline',
                'content' => [
                    'id' => $param['source_id'],
                    'type' => 2
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultOnlineModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约记录-咨询师选择器
     * @return bool|string
     */
    public function ConsultOfflineSelector(): bool|string
    {
        try {
            $ConsultOfflineModel = new ConsultOfflineModel();
            $ConsultIds = $ConsultOfflineModel->where('unit_id', '=', $this->userData['unit_id'])->column('consult_id');
            if (!$ConsultIds) return success();
            $ConsultIds = array_unique($ConsultIds);
            $UserModel = new UserModel();
            $data = $UserModel->where('id', 'in', $ConsultIds)->field('id,name')->select()->toArray();
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约记录
     * @return bool|string
     */
    public function offlineList(): bool|string
    {
        try {
            $param = $this->request->param();
            $where = [];
            if (!empty($param['uid'])) {
                $where[] = ['uid', '=', $param['uid']];
            }
            if (!empty($param['name'])) {
                $UserModel = new UserModel();
                $uid = $UserModel->where([
                    ['unit_id', '=', $this->userData['unit_id']],
                    ['name|username', 'like', '%' . $param['name'] . '%']
                ])->column('id');
                if (!empty($uid)) {
                    $where[] = ['uid', 'in', $uid];
                } else {
                    $where[] = ['uid', '=', -1];
                }
            }
            if (!empty($param['start_time']) && !empty($param['end_time'])) {
                $where[] = ['time', 'between', [$param['start_time'], $param['end_time']]];
            } else {
                if (!empty($param['start_time'])) {
                    $where[] = ['time', '>=', $param['start_time']];
                }
                if (!empty($param['end_time'])) {
                    $where[] = ['time', '<=', $param['end_time']];
                }
            }
            if (isset($param['situation']) && strlen($param['situation']) > 1) {
                $where[] = ['situation', 'in', $param['situation']];
            }
            if (!empty($param['question_id'])) {
                $where[] = ['question_id', 'in', $param['question_id']];
            }
            if (!empty($param['consult_id'])) {
                $where[] = ['consult_id', 'in', $param['consult_id']];
            }
            if (!empty($param['type'])) {
                $where[] = ['type', 'in', $param['type']];
            }
            if (isset($param['is_end']) && strlen($param['is_end']) > 0) {
                $where[] = ['is_end', '=', $param['is_end']];
            }
            if (isset($param['is_follow']) && strlen($param['is_follow']) > 0) {
                $where[] = ['is_follow', '=', $param['is_follow']];
            }
            if (isset($param['is_blacklist']) && strlen($param['is_blacklist']) > 0) {
                $where[] = ['is_blacklist', '=', $param['is_blacklist']];
            }
            if ($this->userData['role_mode'] == 2) {
                $where[] = ['consult_id', '=', $this->userData['id']];
            }
            if (!empty($param['sex'])) {
                //普通用户的性别筛选
                $UserModel = new UserModel();
                $ids = $UserModel->where('sex', '=', $param['sex'])->column('id');
                if (!empty($ids)) {
                    $where[] = ['uid', 'in', $ids];
                } else {
                    $where[] = ['id', '=', -1];
                }
            }
            if (!empty($param['class_id'])) {
                $UserModel = new UserModel();
                $ids = $UserModel->where('department_id', 'in', $param['class_id'])->column('id');
                if (!empty($ids)) {
                    $where[] = ['uid', 'in', $ids];
                } else {
                    $where[] = ['id', '=', -1];
                }
            }
            if (!empty($param['id'])) {
                $where[] = ['id', 'in', $param['id']];
            }
            $where[] = ['unit_id', '=', $this->userData['unit_id']];
            $ConsultDelLogModel = new ConsultDelLogModel();
            $delId = $ConsultDelLogModel->where([
                ['uid', '=', $this->userData['id']],
                ['type', '=', 2]
            ])->column('type_id');
            if (!empty($delId)) {
                $where[] = ['id', 'not in', $delId];
            }
            $ConsultOfflineModel = new ConsultOfflineModel();
            $query = $ConsultOfflineModel->where($where);
            $data = $query->with([
                'user', 'consult', 'questionName', 'ConsultTime'
            ])->order('id desc')->paginate($param['pageSize'])->toArray();
            foreach ($data['data'] as &$item) {
                $item['reservation_time'] = date('Y-m-d H:i', $item['reservation_start_time']) . '-' . date('H:i', $item['reservation_end_time']);
            }
            $data['ids'] = $query->column('id');
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     *  线下高级筛选导出
     * @return bool|string
     */
    public function offlineAdvancedFilteringExport(): bool|string
    {
        try {
            $param = $this->request->param();
            $param['role_mode'] = $this->userData['role_mode'];
            $param['unit_id'] = $this->userData['unit_id'];
            $param['user_id'] = $this->userData['id'];
            $OfflineExportService = new OfflineExportService($this->app);
            $ret = $OfflineExportService->OfflineExport($param);
            if (!$ret) throw new \Exception($OfflineExportService->getMessage());
            return success($OfflineExportService->getResult());
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }


    /**
     * 线下预约记录-删除
     * @return bool|string
     */
    public function offlineDel(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require'
            ]);
            $ConsultantService = new ConsultantService($this->app);
            $ConsultantService->del($param['id'], 2, $this->userData);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约记录-详情
     * @return bool|string
     */
    public function offlineInfo(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOfflineModel = new ConsultOfflineModel();
            $info = $ConsultOfflineModel->with([
                'consult',
                'ConsultTime',
                'task' => function ($query) {
                    $query->with(['RatingScale', 'ConsultOfflineResult']);
                },
                'questionName'
            ])->find($id);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->admin_dot == 1) {
                $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
                $is_dot = $ConsultOfflineTaskModel->where([
                    ['offline_id', '=', $id],
                    ['admin_dot', '=', 1]
                ])->value('id');
                if (!$is_dot) {
                    $info->admin_dot = 0;
                    $info->save();
                }
            }
            $info['appoinment_date'] = date('Y-m-d', $info['reservation_start_time']);
            $info['appoinment_period'] = date('H:i', $info['reservation_start_time']) . '-' . date('H:i', $info['reservation_end_time']);
            return success($info);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约记录-更新预约内容
     * @param Websocket $websocket
     * @return bool|string
     */
    public function offlineUpdate(Websocket $websocket): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|记录ID' => 'require|integer|max:11',
            ]);
            $ConsultOfflineModel = new ConsultOfflineModel();
            $info = $ConsultOfflineModel->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('当前咨询师才能操作！');
            if ($info->end == 1) throw new \Exception('会话已结束！');
            $param['user_dot'] = 1;
            $info->save($param);
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['uid']]);
            $socketServer->push($fd, json_encode([
                'type' => 'consultOffline',
                'content' => [
                    'id' => $param['id'],
                    'type' => 1
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约记录-发送任务
     * @param Websocket $websocket
     * @return bool|string
     */
    public function offlineSendTask(Websocket $websocket): bool|string
    {
        $ConsultOfflineModel = new ConsultOfflineModel();
        $ConsultOfflineModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'offline_id|记录ID' => 'require|integer|max:11',
//                'rating_scale_id|量表ID' => 'require|integer|max:11',
                'type|类型' => 'require|in:1,2',
            ]);
            $info = $ConsultOfflineModel->find($param['offline_id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('当前咨询师才能操作！');
            if ($info->end == 1) throw new \Exception('会话已结束！');
            $info->user_dot = 1;
            $info->save();
            $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
            if ($param['type'] == 2) {
                if (empty($param['rating_scale_id']) || !is_array($param['rating_scale_id'])) throw new \Exception('参数错误！');
                $paramAll = [];
                foreach ($param['rating_scale_id'] as $v) {
                    $paramAll[] = [
                        'offline_id' => $param['offline_id'],
                        'rating_scale_id' => $v,
                        'type' => $param['type'],
                        'time' => time(),
                        'user_dot' => 1
                    ];
                }
                $ConsultOfflineTaskModel->insertAll($paramAll);
            } else {
                $param['user_dot'] = 1;
                $param['time'] = time();
                $ConsultOfflineTaskModel->insert($param);
            }
            $ConsultOfflineModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['uid']]);
            $socketServer->push($fd, json_encode([
                'type' => 'consultOffline',
                'content' => [
                    'id' => $param['offline_id'],
                    'type' => 1
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultOfflineModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约记录-结束本次预约
     * @param Websocket $websocket
     * @return bool|string
     */
    public function offlineEnd(Websocket $websocket): bool|string
    {
        $UserModel = new UserModel();
        $UserModel->startTrans();
        try {
            $id = $this->request->param('id');
            $ConsultOfflineModel = new ConsultOfflineModel();
            $info = $ConsultOfflineModel->find($id);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('只能咨询师结束会话！');
            if ($info->is_end == 1) throw new \Exception('已结束会话！');
            $info->admin_del = 0;
            $info->user_del = 0;
            $info->is_end = 1;
            $info->end_time = time();
            $info->save();
            $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
            $ConsultOfflineTaskModel->where('offline_id', '=', $info->id)->update([
                'admin_dot' => 0,
                'user_dot' => 0
            ]);
            $UserModel->where('id', '=', $info->consult_id)->inc('consult_offline_num')->save();
            //更新用户表，档案更新时间
            $UserModel->where('id', $info->uid)->update(['archive_update_time' => time(), 'is_normal' => 1]);
            $UserModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['uid']]);
            $socketServer->push($fd, json_encode([
                'type' => 'consultOffline',
                'content' => [
                    'id' => $id,
                    'type' => 2
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            $UserModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下咨询-加入黑名单
     * @param Websocket $websocket
     * @return bool|string
     */
    public function offlineAddBlacklist(Websocket $websocket): bool|string
    {
        $ConsultOfflineModel = new ConsultOfflineModel();
        $ConsultOfflineModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'source_id|来源ID' => 'require|integer|max:11',
                'duration|时长' => 'require',
                'reason|原因' => 'require',
            ]);
            $info = $ConsultOfflineModel->find($param['source_id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('咨询师不匹配！');
            if ($info->is_blacklist == 1) throw new \Exception('不可重复拉黑！');
            $param['unit_id'] = $this->userData['unit_id'];
            $param['uid'] = $info->uid;
            $param['consult_id'] = $info->consult_id;
            $param['source'] = 2;
            $param['time'] = time();
            $ConsultBlacklistModel = new ConsultBlacklistModel();
            $info->blacklist_id = $ConsultBlacklistModel->insertGetId($param);
            $info->is_blacklist = 1;
            $UserModel = new UserModel();
            if ($info->is_end == 0) {
                $info->is_end = 1;
                $info->end_time = time();
                $UserModel->where('id', '=', $info->consult_id)->inc('consult_offline_num')->save();
            }
            //取消红点
            $info->admin_dot = 0;
            $info->user_dot = 0;
            $info->save();
            $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
            $ConsultOfflineTaskModel->where('offline_id', '=', $info->id)->update([
                'admin_dot' => 0,
                'user_dot' => 0
            ]);
            //更新用户表，档案更新时间
            $UserModel->where('id', $info->uid)->update(['archive_update_time' => time(), 'is_normal' => 1]);
            $ConsultOfflineModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['uid']]);
            $socketServer->push($fd, json_encode([
                'type' => 'consultOffline',
                'content' => [
                    'id' => $info['id'],
                    'type' => 2
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultOfflineModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }


    /**
     * 黑名单列表
     * @return bool|string
     */
    public function BlacklistList(): bool|string
    {
        try {
            $param = $this->request->param();
            $where = [];
            if (!empty($param['name'])) {
                $UserModel = new UserModel();
                $uids = $UserModel->where('name|username', 'like', '%' . $param['name'] . '%')->column('id');
                if (!empty($uids)) {
                    $where[] = ['uid', 'in', $uids];
                } else {
                    $where[] = ['id', '=', -1];
                }
            }
            if (!empty($param['start_time']) && !empty($param['end_time'])) {
                $where[] = ['time', 'between', [$param['start_time'], $param['end_time']]];
            } else {
                if (!empty($param['start_time'])) {
                    $where[] = ['time', '>=', $param['start_time']];
                }
                if (!empty($param['end_time'])) {
                    $where[] = ['time', '<=', $param['end_time']];
                }
            }
            if (!empty($param['source'])) {
                $where[] = ['source', 'in', $param['source']];
            }
            if (!empty($param['reason'])) {
                $where[] = ['reason', 'in', $param['reason']];
            }
            if (!empty($param['duration']) || (isset($param['duration']) && strlen($param['duration']) > 0)) {
                $where[] = ['duration', 'in', $param['duration']];
            }
            if (!empty($param['consult_id'])) {
                $where[] = ['consult_id', 'in', $param['consult_id']];
            }
            if (!empty($param['class_id'])) {
                $UserModel = new UserModel();
                $ids = $UserModel->where('department_id', 'in', $param['class_id'])->column('id');
                if (!empty($ids)) {
                    $where[] = ['uid', 'in', $ids];
                } else {
                    $where[] = ['id', '=', -1];
                }
            }
            if (!empty($param['id'])) {
                $where[] = ['id', 'in', $param['id']];
            }
            $where[] = ['unit_id', '=', $this->userData['unit_id']];
            $ConsultBlacklistModel = new ConsultBlacklistModel();
            $query = $ConsultBlacklistModel->where($where);
            $data = $query->with([
                'user', 'consult'
            ])->order('id desc')->paginate($param['pageSize'])->toArray();
            $data['ids'] = $query->column('id');
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     *  黑名单高级筛选导出
     * @return bool|string
     */
    public function exportBlacklist(): bool|string
    {
        try {
            $param = $this->request->param();
            $param['role_mode'] = $this->userData['role_mode'];
            $param['unit_id'] = $this->userData['unit_id'];
            $param['user_id'] = $this->userData['id'];
            $param['blackout_duration'] = $this->blackoutDuration(); //拉黑时长
            $param['black_reason'] = $this->blackReason(); //拉黑原因
            $exportBlackService = new ExportBlackService($this->app);
            $ret = $exportBlackService->exportBlack($param);
            if (!$ret) throw new \Exception($exportBlackService->getMessage());
            return success($exportBlackService->getResult());
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 黑名单列表-删除
     * @return bool|string
     */
    public function BlacklistDel(): bool|string
    {
        $id = $this->request->param('id');
        $ConsultBlacklistModel = new ConsultBlacklistModel();
        $ConsultBlacklistModel->startTrans();
        try {
            if (is_array($id)) {
                foreach ($id as $v) {
                    $info = $ConsultBlacklistModel->find($v);
                    if (!$info) throw new \Exception('参数错误！');
                    if ($info->consult_id != $this->userData['id']) throw new \Exception('对应咨询师才可移除！');
                    if ($info->source == 1) {
                        $ConsultOnlineModel = new ConsultOnlineModel();
                        $ConsultOnlineModel->where([
                            'uid' => $info->uid,
                            'consult_id' => $info->consult_id
                        ])->update(['is_blacklist' => 0]);
                    } else {
                        $ConsultOfflineModel = new ConsultOfflineModel();
                        $ConsultOfflineModel->where([
                            'uid' => $info->uid,
                            'consult_id' => $info->consult_id
                        ])->update(['is_blacklist' => 0]);
                    }
                    $info->is_del = 1;
                    $info->del_time = time();
                    $info->save();
                }
            } else {
                $info = $ConsultBlacklistModel->find($id);
                if (!$info) throw new \Exception('参数错误！');
                if ($info->consult_id != $this->userData['id']) throw new \Exception('对应咨询师才可移除！');
                if ($info->source == 1) {
                    $ConsultOnlineModel = new ConsultOnlineModel();
                    $ConsultOnlineModel->where([
                        'uid' => $info->uid,
                        'consult_id' => $info->consult_id
                    ])->update(['is_blacklist' => 0]);
                } else {
                    $ConsultOfflineModel = new ConsultOfflineModel();
                    $ConsultOfflineModel->where([
                        'uid' => $info->uid,
                        'consult_id' => $info->consult_id
                    ])->update(['is_blacklist' => 0]);
                }
                $info->is_del = 1;
                $info->del_time = time();
                $info->save();
            }
            $ConsultBlacklistModel->commit();
            return success();
        } catch (\Exception $e) {
            $ConsultBlacklistModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }


    /**
     * 每月每月排班视图
     * @return bool|string
     */
    public function SchedulingView(): bool|string
    {
        try {
            $param = $this->request->param();//Y-m
            $this->validate($param, [
                'date|时间' => 'require',
            ]);
            $date_time = strtotime($param['date'] . '-01');
            $t = date('t', $date_time);
            $start_time = date('Ym01', $date_time);
            $end_time = date('Ym' . $t, $date_time);
            $where = [];
            $where[] = ['unit_id', '=', $this->userData['unit_id']];
            $where[] = ['date', 'between', [$start_time, $end_time]];
            $ConsultTimeModel = new ConsultTimeModel();
            $list = $ConsultTimeModel->where($where)->with([
                'consult'
            ])->select()->toArray();
            $data = [];
            foreach ($list as $item) {
                $data[$item['date']][$item['consult_id']][] = $item;
            }
            $data2 = [];
            foreach ($data as $key => $item) {
                $users = [];
                foreach ($item as $items) {
                    $nickname = '';
                    $appointment = [];
                    foreach ($items as $v) {
                        $nickname = $v['consult_name'];
                        $appointment[] = [
                            'start' => date('H:i', $v['start_time']),
                            'end' => date('H:i', $v['end_time']),
                            'is_reservation' => $v['is_reservation'],
                            'model' => $v['model'],
                        ];
                    }
                    $users[] = [
                        'nickname' => $nickname,
                        'appointment' => $appointment,
                    ];
                }
                $data2[] = [
                    'date' => strtotime($key),
                    'users' => $users
                ];
            }
            return success($data2);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 排班列表
     * @return bool|string
     */
    public function SchedulingList(): bool|string
    {
        try {
            $param = $this->request->param();
            $where = [];
            if ($this->userData['role_mode'] == 2) {
                $where[] = ['id', '=', $this->userData['id']];
            } else {
                $where[] = ['role_mode', '=', 2];
            }
            $where[] = ['unit_id', '=', $this->userData['unit_id']];
            $UserModel = new UserModel();
            $data = $UserModel->where($where)->with([
                'userTag' => function ($query) {
                    $query->with(['tag']);
                }
            ])->paginate($param['pageSize'])->toArray();
            $ConsultTimeModel = new ConsultTimeModel();
            foreach ($data['data'] as &$item) {
                //服务对象
                $department_id = $ConsultTimeModel->where([
                    ['consult_id', '=', $item['id']],
                    ['start_time', '>', time()]
                ])->order('time desc')->field('model,department_id,time')->find();
                if ($department_id) {
                    if ($department_id['department_id'] == 0) {
                        $ServerObject = '所有部门';
                    } else {
                        $ServerObject = '服务指定部门';
                    }
                    //排班服务类型
                    $ServerType = match ($department_id['model']) {
                        1 => '线下预约',
                        default => '--',
                    };
                    //排班情况
                    $ConsultDate = $ConsultTimeModel->where([
                        ['consult_id', '=', $item['id']],
                        ['start_time', '>', time()]
                    ])->distinct(true)->column('date');
                    $day = count($ConsultDate);
                    //排班更新时间
                    $updateTime = $department_id['time'];
                    $item['is_scheduling'] = $day ? '有' : '无'; //有无排班
                    $item['scheduling_day'] = $day ? $day . '天' : '--'; //排班情况
                    $item['service_object'] = $ServerObject;//服务对象 [指定部门或者所有部门]
                    $item['service_type'] = $ServerType;//服务类型
                    $item['update_time'] = $updateTime;//排班更新时间
                } else {
                    $item['is_scheduling'] = '无'; //有无排班
                    $item['scheduling_day'] = '--'; //排班情况
                    $item['service_object'] = '--';//服务对象 [指定部门或者所有部门]
                    $item['service_type'] = '--';//服务类型
                    $item['update_time'] = '';//排班更新时间
                }
            }
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 清空排班
     * @return bool|string
     */
    public function SchedulingDel(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultTimeModel = new ConsultTimeModel();
            $ConsultTimeModel->startTrans();
//            $is_reservation = $ConsultTimeModel->where([
//                'consult_id' => $id,
//                'is_reservation' => 1
//            ])->value('id');
//            if ($is_reservation) throw new \Exception('有预约,不可清空！');
            $ConsultTimeModel->where('consult_id', '=', $id)->update([
                'is_del' => 1,
                'del_time' => time()
            ]);
            $uid = $ConsultTimeModel->where([
                ['consult_id', '=', $id],
                ['uid', '>', 0]
            ])->column('uid');
            if (!empty($uid)) {
                $uid = array_unique($uid);
                $MessageData = [];
                $UserModel = new UserModel();
                $consult_name = $UserModel->where('id', '=', $id)->value('name');
                foreach ($uid as $v) {
                    $MessageData[] = [
                        'uid' => $v,
                        'type' => 24,
                        'title' => '取消预约',
                        'content' => '您于' . date('Y-m-d') . '日期' . date('H:i:s') . '时间向' . $consult_name . '咨询师提交的线下预约申请，因咨询师取消排班已失效，请选择其它时间重新预约。',
                        'time' => time()
                    ];
                }
                if (!empty($MessageData)) {
                    $MessageModel = new MessageModel();
                    $MessageModel->insertAll($MessageData);
                }
            }
            $UserModel = new UserModel();
            $UserModel->where('id', '=', $id)->update([
                'is_scheduling' => 0
            ]);
            $ConsultTimeModel->commit();
            return success();
        } catch (\Exception $e) {
            $ConsultTimeModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 添加排班
     * @return bool|string
     */
    public function SchedulingAdd(): bool|string
    {
        /**
         *如果设置选择覆盖
         * 一.覆盖
         *  1.规则：新增的排班日期如果有已经被用户预约的数据，那么这一整天就不能覆盖。如果没有则整天的数据全部覆盖。、
         *     具体步骤：1.先查询新增的排班日期里有没有数据，没有数据直接越过这一步【同下】
         *              2.有数据，查询出要覆盖的日期，判断是否有被预约的用户。有的话直接跳过这一天。没有就新增这一天的排班数据
         * 二.不覆盖
         *  1.规则：如果新做的排班日期有数据则整天的数据都不覆盖.不管这一天有没有被用户预约
         *      具体步骤：1.先查询新增的排班日期里有没有数据，没有数据直接越过这一步。【同上】
         */
        $ConsultTimeModel = new ConsultTimeModel();
        $ConsultTimeModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'model|模板' => 'require',
                'is_cover|覆盖方式' => 'require',
                'duration|间隔时段' => 'require',
                'end_date|结束时间' => 'require',
                'start_date|开始时间' => 'require',
                'department_id|部门' => 'require',
//                'address|预约地址' => 'require',
                'consult_id|咨询师' => 'require',
            ]);
            $dayDiff = $param['end_date'] - $param['start_date'];//获取日期差值
            $day_num = $dayDiff / (24 * 60 * 60);//得出排班日期有多少天
            $day_num += 1;//2024-8-20~2024-8-20【差值是0，算一天】
//            $year = date('Y', $param['start_date']);
//            $month = date('m', $param['start_date']);
            $time = time();
            $dateData = [];
            $SaveData = [];
            for ($j = 0; $j < $day_num; $j++) {
                $timed = $j * 24 * 60 * 60;
                $currentDate = $param['start_date'] + $timed;
                $year = date('Y', $currentDate);
                $month = date('m', $currentDate);
                $day = date('d', $currentDate);
                // $day = date('d', $param['start_date'] + $timed);//每循环一次加一天的时间
                $date = $year . $month . $day;
                if ($param['is_cover'] == 1) {
                    $is_day_value = $ConsultTimeModel->where([
                        ['consult_id', '=', $param['consult_id']],
                        ['date', '=', $date],
                        ['is_reservation', '=', 1]
                    ])->value('id');
                } else {
                    $is_day_value = $ConsultTimeModel->where([
                        ['consult_id', '=', $param['consult_id']],
                        ['date', '=', $date]
                    ])->value('id');
                }
                if ($is_day_value) continue;

                $dateData[] = $date;
                //上午
                if (!empty($param['early_start_time']) && !empty($param['early_end_time'])) {
                    $duration = $param['duration'] * 60; // 将分钟转换为秒
                    $interval = $param['early_end_time'] - $param['early_start_time'];//获取时长
                    $num = $interval / $duration;//排班分成了多少个时段
                    $ymd = $year . '-' . $month . '-' . $day;
                    $early_start_time = strtotime($ymd . ' ' . date('H:i:s', $param['early_start_time']));
                    $start_time = $early_start_time;
                    for ($i = 1; $i <= $num; $i++) {
                        $SaveData[] = [
                            'unit_id' => $this->userData['unit_id'],
                            'department_id' => $param['department_id'] ?? 0,
                            'consult_id' => $param['consult_id'],
                            'model' => $param['model'],
                            'address' => $param['address'],
                            'date' => $date,
                            'start_time' => $start_time,
                            'end_time' => $early_start_time + ($i * $duration),
                            'time' => $time
                        ];
                        $start_time = $early_start_time + ($i * $duration);
                    }
                }
                //下午
                if (!empty($param['midday_start_time']) && !empty($param['midday_end_time'])) {
                    $duration = $param['duration'] * 60; // 将分钟转换为秒
                    $interval = $param['midday_end_time'] - $param['midday_start_time'];//获取时长
                    $num = $interval / $duration;//排班分成了多少个时段
                    $ymd = $year . '-' . $month . '-' . $day;
                    $midday_start_time = strtotime($ymd . ' ' . date('H:i:s', $param['midday_start_time']));
                    $start_time = $midday_start_time;
                    for ($i = 1; $i <= $num; $i++) {
                        $SaveData[] = [
                            'unit_id' => $this->userData['unit_id'],
                            'department_id' => $param['department_id'] ?? 0,
                            'consult_id' => $param['consult_id'],
                            'model' => $param['model'],
                            'address' => $param['address'],
                            'date' => $date,
                            'start_time' => $start_time,
                            'end_time' => $midday_start_time + ($i * $duration),
                            'time' => $time
                        ];
                        $start_time = $midday_start_time + ($i * $duration);
                    }
                }
                //晚上
                if (!empty($param['nightshift_start_time']) && !empty($param['nightshift_end_time'])) {
                    $duration = $param['duration'] * 60; // 将分钟转换为秒
                    $interval = $param['nightshift_end_time'] - $param['nightshift_start_time'];//获取时长
                    $num = $interval / $duration;//排班分成了多少个时段
                    $ymd = $year . '-' . $month . '-' . $day;
                    $nightshift_start_time = strtotime($ymd . ' ' . date('H:i:s', $param['nightshift_start_time']));
                    $start_time = $nightshift_start_time;
                    for ($i = 1; $i <= $num; $i++) {
                        $SaveData[] = [
                            'unit_id' => $this->userData['unit_id'],
                            'department_id' => $param['department_id'] ?? 0,
                            'consult_id' => $param['consult_id'],
                            'model' => $param['model'],
                            'address' => $param['address'],
                            'date' => $date,
                            'start_time' => $start_time,
                            'end_time' => $nightshift_start_time + ($i * $duration),
                            'time' => $time
                        ];
                        $start_time = $nightshift_start_time + ($i * $duration);
                    }
                }
            }
            if (!empty($dateData)) {
                $ConsultTimeModel->where([
                    ['consult_id', '=', $param['consult_id']],
                    ['date', 'in', $dateData],
                ])->update([
                    'is_del' => 1,
                    'del_time' => $time
                ]);
            }
            if (!empty($SaveData)) {
                $ConsultTimeModel->insertAll($SaveData);
            }
            //排班成功之后修改User表此咨询的排班状态
            UserModel::query()->where('id', $param['consult_id'])->update(['is_scheduling' => 1]);
            $ConsultTimeModel->commit();
            return success();
        } catch (\Exception $e) {
            $ConsultTimeModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 删除排班时间段
     * @return bool|string
     */
    public function TimeDel(): bool|string
    {
        $ConsultTimeModel = new ConsultTimeModel();
        $ConsultTimeModel->startTrans();
        try {
            $id = $this->request->param('id');
            $info = $ConsultTimeModel->find($id);
            if (!$info) throw new \Exception('参数错误！');
            $info->save([
                'is_del' => 1,
                'del_time' => time()
            ]);
            $is_scheduling = $ConsultTimeModel->where('consult_id', '=', $info['consult_id'])->value('id');
            if (!$is_scheduling) {
                $UserModel = new UserModel();
                $UserModel->where('id', '=', $info['consult_id'])->update([
                    'is_scheduling' => 0
                ]);
            }
            $ConsultTimeModel->commit();
            return success();
        } catch (\Exception $e) {
            $ConsultTimeModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 每月每月排班视图-个人
     * @return bool|string
     */
    public function PersonSchedulingView(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'date|时间' => 'require',
                'consult_id|咨询师' => 'require',
            ]);
            $date_time = strtotime($param['date'] . '-01');
            $t = date('t', $date_time);
            $start_time = date('Ym01', $date_time);
            $end_time = date('Ym' . $t, $date_time);
            $where = [];
            $where[] = ['date', 'between', [$start_time, $end_time]];
            $where[] = ['consult_id', '=', $param['consult_id']];
            $where[] = ['model', '=', $param['model']];
            $ConsultTimeModel = new ConsultTimeModel();
            $list = $ConsultTimeModel->where($where)->with(['user'])->select()->toArray();
            $data = [];
            $UserService = new UserService($this->app);
            $getNotDelDepartmentAffiliationAll = $UserService->getNotDelDepartmentAffiliationAll($this->userData['unit_id']);
            foreach ($list as $item) {
                $item['department_name'] = $getNotDelDepartmentAffiliationAll[$item['user_department_id']]['all_name'] ?? '--';
                $item['start'] = date('H:i', $item['start_time']);
                $item['end'] = date('H:i', $item['end_time']);
                $data[$item['date']][] = $item;
            }
            $data2 = [];
            foreach ($data as $key => $item) {
                $data2[] = [
                    'date' => strtotime($key),
                    'time' => $item
                ];
            }
            return success($data2);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询-查看测评结果
     * @return bool|string
     */
    public function OnlineViewResult(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOnlineMessageModel = new ConsultOnlineMessageModel();
            $info = $ConsultOnlineMessageModel->find($id);
            if (!$info) throw new \Exception('参数错误！');
            $ReportService = new ReportService($this->app);
            $data = $ReportService->OnlineReportInfo($info->result_id);
            if ($info->admin_dot == 1) {
                $info->admin_dot = 0;
                $info->save();
            }
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约-查看测评结果
     * @return bool|string
     */
    public function OfflineViewResult(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
            $info = $ConsultOfflineTaskModel->find($id);
            if (!$info) throw new \Exception('参数错误！');
            $ReportService = new ReportService($this->app);
            $data = $ReportService->OfflineReportInfo($info->result_id);
            if ($info->admin_dot == 1) {
                $info->admin_dot = 0;
                $info->save();
            }
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 设置线上咨询测评结果查看权限
     * @param Websocket $websocket
     * @return bool|string
     */
    public function OnlineViewResultAuth(Websocket $websocket): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require|integer|max:11',
                'result_read_auth|查看权限' => 'require|integer|max:1',
            ]);
            $ConsultOnlineMessageModel = new ConsultOnlineMessageModel();
            $info = $ConsultOnlineMessageModel->with(['ConsultOnline'])->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('咨询师本人才可操作！');
            $info->result_read_auth = $param['result_read_auth'];
            $info->save();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['online_uid']]);
            $socketServer->push($fd, json_encode([
                'type' => 'consultOnline',
                'content' => [
                    'id' => $info['online_id'],
                    'type' => 1
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 设置线下预约测评结果查看权限
     * @param Websocket $websocket
     * @return bool|string
     */
    public function OfflineViewResultAuth(Websocket $websocket): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require|integer|max:11',
                'result_read_auth|查看权限' => 'require|integer|max:1',
            ]);
            $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
            $info = $ConsultOfflineTaskModel->with(['ConsultOffline'])->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('咨询师本人才可操作！');
            $info->result_read_auth = $param['result_read_auth'];
            $info->save();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['uid']]);
            $socketServer->push($fd, json_encode([
                'type' => 'consultOffline',
                'content' => [
                    'id' => $info['offline_id'],
                    'type' => 1
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约-结果里的加入关注人群
     * @return bool|string
     */
    public function OfflineAddFollow(): bool|string
    {
        $ConsultOfflineResultModel = new ConsultOfflineResultModel();
        $ConsultOfflineResultModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require|integer|max:11',
                'level|关注等级' => 'require',
                'reason|关注原因' => 'require',
            ]);
            $info = $ConsultOfflineResultModel->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
            $OfflineId = $ConsultOfflineTaskModel->where('id', '=', $info['source_id'])->value('offline_id');
            $ConsultOfflineModel = new ConsultOfflineModel();
            $ConsultOfflineInfo = $ConsultOfflineModel->find($OfflineId);
            if (!$ConsultOfflineInfo) throw new \Exception('参数错误！');
            if ($ConsultOfflineInfo->consult_id != $this->userData['id']) throw new \Exception('咨询师本人才可操作！');
            $ConsultOfflineInfo->is_follow = 1;
            $ConsultOfflineInfo->save();
            $FollowUserModel = new FollowUserModel();
            $FollowUserModel->insert([
                'unit_id' => $this->userData['unit_id'],
                'operator_uid' => $this->userData['id'],
                'uid' => $info->uid,
                'level' => $param['level'],
                'reason' => $param['reason'],
                'channel' => 7,
                'channel_id' => $param['id'],
                'time' => time()
            ]);
            $info->is_follow = 1;
            $info->save();
            $ConsultOfflineResultModel->commit();
            return success();
        } catch (\Exception $e) {
            $ConsultOfflineResultModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询-结果里的加入关注人群
     * @return bool|string
     */
    public function OnlineAddFollow(): bool|string
    {
        $ConsultOnlineResultModel = new ConsultOnlineResultModel();
        $ConsultOnlineResultModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require|integer|max:11',
                'level|关注等级' => 'require',
                'reason|关注原因' => 'require',
            ]);
            $info = $ConsultOnlineResultModel->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            $ConsultOnlineMessageModel = new ConsultOnlineMessageModel();
            $online_id = $ConsultOnlineMessageModel->where('id', '=', $info['source_id'])->value('online_id');
            $ConsultOnlineModel = new ConsultOnlineModel();
            $ConsultOnlineInfo = $ConsultOnlineModel->find($online_id);
            if (!$ConsultOnlineInfo) throw new \Exception('参数错误！');
            if ($ConsultOnlineInfo->consult_id != $this->userData['id']) throw new \Exception('咨询师本人才可操作！');
            $ConsultOnlineInfo->is_follow = 1;
            $ConsultOnlineInfo->save();
            $FollowUserModel = new FollowUserModel();
            $FollowUserModel->insert([
                'unit_id' => $this->userData['unit_id'],
                'operator_uid' => $this->userData['id'],
                'uid' => $info->uid,
                'level' => $param['level'],
                'reason' => $param['reason'],
                'channel' => 6,
                'channel_id' => $param['id'],
                'time' => time()
            ]);
            $info->is_follow = 1;
            $info->save();
            $ConsultOnlineResultModel->commit();
            return success();
        } catch (\Exception $e) {
            $ConsultOnlineResultModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询-报告详情
     * @return bool|string
     */
    public function OnlineReportInfo(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ReportService = new ReportService($this->app);
            return success($ReportService->OnlineReportInfo($id));
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约-报告详情
     * @return bool|string
     */
    public function OfflineReportInfo(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ReportService = new ReportService($this->app);
            return success($ReportService->OfflineReportInfo($id));
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 文章列表
     * @return bool|string
     */
    public function articleList(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'pageSize|每页显示数量' => 'require'
            ]);
            $where[] = ['unit_id', '=', $this->userData['unit_id']];
            $ConsultArticleModel = new ConsultArticleModel();
            $query = $ConsultArticleModel->where($where);
            $data = $query->paginate($param['pageSize'])->toArray();
            $data['ids'] = $query->column('id');
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }


    /**
     * 文章详情
     * @return bool|string
     */
    public function articleInfo(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require',
            ]);
            $ConsultArticleModel = new ConsultArticleModel();
            $info = $ConsultArticleModel->with([
                'user'
            ])->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            return success($info);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 文章添加
     * @return bool|string
     */
    public function articleAdd(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'title|标题' => 'require',
                'content|内容' => 'require'
            ]);
            $param['unit_id'] = $this->userData['unit_id'];
            $param['up_time'] = time();
            $param['time'] = time();
            $ConsultArticleModel = new ConsultArticleModel();
            $ConsultArticleModel->insert($param);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 文章更新
     * @return bool|string
     */
    public function articleUpdate(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require',
            ]);
            $ConsultArticleModel = new ConsultArticleModel();
            $info = $ConsultArticleModel->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            $param['up_time'] = time();
            $info->save($param);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 文章删除
     * @return bool|string
     */
    public function articleDel(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require',
            ]);
            $ConsultArticleModel = new ConsultArticleModel();
            $ConsultArticleModel->where('id', 'in', $param['id'])->update([
                'is_del' => 1,
                'del_time' => time()
            ]);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 文章示例列表
     * @return bool|string
     */
    public function articleTestList(): bool|string
    {
        try {
            $ConsultArticleTestModel = new ConsultArticleTestModel();
            $data = $ConsultArticleTestModel->where('unit_id', '=', $this->userData['unit_id'])->select()->toArray();
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 文章示例详情
     * @return bool|string
     */
    public function articleTestInfo(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require',
            ]);
            $ConsultArticleTestModel = new ConsultArticleTestModel();
            $info = $ConsultArticleTestModel->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            return success($info);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 文章示例更新
     * @return bool|string
     */
    public function articleTestUpdate(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'type|类型' => 'require',
                'title|标题' => 'require',
                'content|内容' => 'require'
            ]);
            $param['up_time'] = time();
            $ConsultArticleTestModel = new ConsultArticleTestModel();
            if (!empty($param['id'])) {
                $info = $ConsultArticleTestModel->find($param['id']);
                if (!$info) throw new \Exception('参数错误！');
                $info->save($param);
            } else {
                $id = $ConsultArticleTestModel->where([
                    ['unit_id','=',$this->userData['unit_id']],
                    ['type','=',$param['type']],
                ])->value('id');
                if (!empty($id)){
                    $param['id'] = $id;
                }
                $param['unit_id'] = $this->userData['unit_id'];
                $param['time'] = time();
                $ConsultArticleTestModel->save($param);
            }
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 咨询师列表
     * @return bool|string
     */
    public function consultantList(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'pageSize|每页显示数量' => 'require'
            ]);
            $UserModel = new UserModel();
            $data = $UserModel->where([
                ['unit_id', '=', $this->userData['unit_id']],
                ['role_mode', '=', 2]
            ])->with([
                'roleName',
                'userTag' => function ($query) {
                    $query->with(['tag']);
                }
            ])->paginate($param['pageSize'])->toArray();
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 心理评估记录
     * @return bool|string
     */
    public function evaluateList(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'pageSize|每页显示数量' => 'require'
            ]);
            $UserModel = new UserModel();
            $ConsultEvaluateModel = new ConsultEvaluateModel();
            $where = [];
            if (!empty($param['name'])) {
                $uid = $UserModel->where([
                    ['unit_id', '=', $this->userData['unit_id']],
                    ['name|username', 'like', '%' . $param['name'] . '%']
                ])->column('id');
                if (!empty($uid)) {
                    $where[] = ['uid', 'in', $uid];
                } else {
                    $where[] = ['id', '=', -1];
                }
            }
            if (!empty($param['start_time']) && !empty($param['end_time'])) {
                $where[] = ['time', 'between', [$param['start_time'], $param['end_time']]];
            } else {
                if (!empty($param['start_time'])) {
                    $where[] = ['time', '>=', $param['start_time']];
                }
                if (!empty($param['end_time'])) {
                    $where[] = ['time', '<=', $param['end_time']];
                }
            }
            if (!empty($param['consult_id'])) {
                $where[] = ['consult_id', 'in', $param['consult_id']];
            }
            if (!empty($param['department_id'])) {
                $uid = $UserModel->where('department_id', '=', $param['department_id'])->column('id');
                if (!empty($uid)) {
                    $where[] = ['uid', 'in', $uid];
                } else {
                    $where[] = ['id', '=', -1];
                }
            }
            if (isset($param['is_follow']) && strlen($param['is_follow']) > 0) {
                $where[] = ['is_follow', '=', $param['is_follow']];
            }
            if (isset($param['is_blacklist']) && strlen($param['is_blacklist']) > 0) {
                $where[] = ['is_blacklist', '=', $param['is_blacklist']];
            }
            if (isset($param['is_end']) && strlen($param['is_blacklist']) > 0) {
                $where[] = ['is_end', '=', $param['is_end']];
            }
            if (!empty($param['uid'])) {
                $where[] = ['uid', '=', $param['uid']];
            }
            $where[] = ['unit_id', '=', $this->userData['unit_id']];
            $ConsultDelLogModel = new ConsultDelLogModel();
            $delId = $ConsultDelLogModel->where([
                ['uid', '=', $this->userData['id']],
                ['type', '=', 3]
            ])->column('type_id');
            if (!empty($delId)) {
                $where[] = ['id', 'not in', $delId];
            }
            $data = $ConsultEvaluateModel->where($where)->with([
                'user',
                'consult',
                'consultTime'
            ])->paginate($param['pageSize'])->toArray();
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估删除
     * @return bool|string
     */
    public function evaluateDel(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require'
            ]);
            $ConsultantService = new ConsultantService($this->app);
            $ConsultantService->del($param['id'], 3, $this->userData);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估详情
     * @return bool|string
     */
    public function evaluateInfo(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require'
            ]);
            $ConsultEvaluateModel = new ConsultEvaluateModel();
            $info = $ConsultEvaluateModel->with([
                'consult',
                'consultTime'
            ])->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            $info->save([
                'admin_dot' => 0
            ]);
            return success($info);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估更新
     * @param Websocket $websocket
     * @return bool|string
     */
    public function evaluateUpdate(Websocket $websocket): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require'
            ]);
            $ConsultEvaluateModel = new ConsultEvaluateModel();
            $info = $ConsultEvaluateModel->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            $param['user_dot'] = 1;
            $info->save($param);
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['uid']]);
            $socketServer->push($fd, json_encode([
                'type' => 'consultEvaluate',
                'content' => [
                    'id' => $param['id'],
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估结束
     * @param Websocket $websocket
     * @return bool|string
     */
    public function evaluateEnd(Websocket $websocket): bool|string
    {
        $ConsultEvaluateModel = new ConsultEvaluateModel();
        $ConsultEvaluateModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require'
            ]);
            $info = $ConsultEvaluateModel->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('只能咨询师结束会话！');
            if ($info->is_end == 1) throw new \Exception('已结束会话！');
            $info->save([
                'admin_del' => 0,
                'user_del' => 0,
                'is_end' => 1,
                'end_time' => time()
            ]);
            $UserModel = new UserModel();
            $UserModel->where('id', '=', $info->consult_id)->inc('consult_evaluate_num')->save();
            $ConsultEvaluateModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['uid']]);
            $socketServer->push($fd, json_encode([
                'type' => 'consultEvaluate',
                'content' => [
                    'id' => $param['id'],
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultEvaluateModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估拉黑
     * @param Websocket $websocket
     * @return bool|string
     */
    public function evaluateAddBlacklist(Websocket $websocket): bool|string
    {
        $ConsultEvaluateModel = new ConsultEvaluateModel();
        $ConsultEvaluateModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'source_id|来源ID' => 'require|integer|max:11',
                'duration|时长' => 'require',
                'reason|原因' => 'require',
            ]);
            $info = $ConsultEvaluateModel->find($param['source_id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('咨询师不匹配！');
            if ($info->is_blacklist == 1) throw new \Exception('不可重复拉黑！');
            $param['unit_id'] = $this->userData['unit_id'];
            $param['uid'] = $info->uid;
            $param['consult_id'] = $info->consult_id;
            $param['source'] = 3;
            $param['time'] = time();
            $ConsultBlacklistModel = new ConsultBlacklistModel();
            $info->blacklist_id = $ConsultBlacklistModel->insertGetId($param);
            $info->is_blacklist = 1;
            $UserModel = new UserModel();
            if ($info->is_end == 0) {
                $info->is_end = 1;
                $info->end_time = time();
                $UserModel->where('id', '=', $info->consult_id)->inc('consult_evaluate_num')->save();
            }
            //取消红点
            $info->admin_dot = 0;
            $info->user_dot = 0;
            $info->save();
            $ConsultEvaluateModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['uid']]);
            $socketServer->push($fd, json_encode([
                'type' => 'consultEvaluate',
                'content' => [
                    'id' => $param['source_id'],
                ]
            ]), $websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultEvaluateModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估加入关注人群
     * @return bool|string
     */
    public function evaluateAddFollow(): bool|string
    {
        $ConsultEvaluateModel = new ConsultEvaluateModel();
        $ConsultEvaluateModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require|integer|max:11',
                'level|关注等级' => 'require',
                'reason|关注原因' => 'require',
            ]);
            $info = $ConsultEvaluateModel->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->consult_id != $this->userData['id']) throw new \Exception('咨询师本人才可操作！');
            $FollowUserModel = new FollowUserModel();
            $FollowUserModel->insert([
                'unit_id' => $this->userData['unit_id'],
                'operator_uid' => $this->userData['id'],
                'uid' => $info->uid,
                'level' => $param['level'],
                'reason' => $param['reason'],
                'channel' => 13,
                'channel_id' => $param['id'],
                'time' => time()
            ]);
            $info->save([
                'is_follow' => 1
            ]);
            $ConsultEvaluateModel->commit();
            return success();
        } catch (\Exception $e) {
            $ConsultEvaluateModel->rollback();
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 排班
     * @return bool|string
     */
    public function scheduling(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'consult_id|咨询师' => 'require',
                'start_time|开始时间' => 'require',
                'end_time|结束时间' => 'require',
                'is_cover|是否覆盖' => 'require',
                'time_slot|时段' => 'require'
            ]);
            $ConsultTimeModel = new ConsultTimeModel();
            $num = ceil(($param['end_time'] - $param['start_time']) / 86400);
            $dateData = [];
            for ($i = 0; $i < $num; $i++) {
                $start_time = $param['start_time'] + (86400 * $i);
                $dateData[] = $date = date('Ymd', $start_time);
                foreach ($param['time_slot'] as $item) {
                    $startHis = date("H:i:00", $item['start_time']);
                    $endHis = date("H:i:59", $item['end_time']);
                    $data[] = [
                        'unit_id' => $this->userData['unit_id'],
                        'consult_id' => $param['consult_id'],
                        'model' => $item['model']??1,
                        'date' => $date,
                        'start_time' => strtotime(date('Y-m-d '.$startHis, $start_time)),
                        'end_time' => strtotime(date('Y-m-d '.$endHis, $start_time)),
                        'time' => time()
                    ];
                }
            }
            if ($param['is_cover'] == 1) {
                $ConsultTimeModel->where([
                    ['consult_id', '=', $param['consult_id']],
                    ['date', 'in', $dateData]
                ])->update([
                    'is_del' => 1,
                    'del_time' => time()
                ]);
            }
            if (!empty($data)) {
                $ConsultTimeModel->insertAll($data,200);
            }
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 存储排班缓存
     * @return bool|string
     */
    public function setSchedulingCache(): bool|string
    {
        try {
            $param = $this->request->param();
            cache(env('REDIS_PROJECT') . 'schedulingCache_' . $this->userData['unit_id'], $param);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 获取排班缓存
     * @return bool|string
     */
    public function getSchedulingCache(): bool|string
    {
        try {
            return success(cache(env('REDIS_PROJECT') . 'schedulingCache_' . $this->userData['unit_id']));
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 排班咨询师信息-高校版添加
     * @return bool|string
     */
    public function schedulingInfo(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'consult_id|咨询师ID' => 'require'
            ]);
            $ConsultTimeModel = new ConsultTimeModel();
            $UserModel = new UserModel();
            $info = $UserModel->field('id,name,age,sex,avatar,role_id,consultant_introduction')->with([
                'roleName',
                'userTag' => function($query){
                    $query->with(['tag']);
                }
            ])->find($param['consult_id']);
            if (!$info) throw new \Exception('参数错误！');
            $info = $info->toArray();
            //服务对象
            $department_id = $ConsultTimeModel->where([
                ['consult_id', '=', $param['consult_id']],
                ['start_time', '>', time()]
            ])->order('time desc')->field('model,department_id,time')->find();
            if ($department_id) {
                //排班情况
                $day = $ConsultTimeModel->where([
                    ['consult_id', '=', $param['consult_id']],
                    ['start_time', '>', time()]
                ])->distinct(true)->count('date');
                //排班更新时间
                $updateTime = $department_id['time'];
                $info['is_scheduling'] = $day ? '有' : '无'; //有无排班
                $info['scheduling_day'] = $day ? $day . '天' : '--'; //排班情况
                $info['update_time'] = $updateTime;//排班更新时间
            } else {
                $info['is_scheduling'] = '无'; //有无排班
                $info['scheduling_day'] = '--'; //排班情况
                $info['update_time'] = '';//排班更新时间
            }
            return success($info);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }


}